package com.zf.yichat.utils.XSpay;

import com.alibaba.fastjson.JSONObject;
import com.zf.yichat.utils.XSpay.TransForm.BaseTransForm;
import com.zf.yichat.utils.XSpay.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.PrivateKey;
import java.util.Map;

public class XSpayService {
    private static Logger logger = LoggerFactory.getLogger(XSpayService.class);

    private static volatile XSpayService instance;
    //新生签名使用的算法
    private static String ALGORITHM = "RSA";
    //类型
    private static String SIGN_ALGORITHM = "SHA1withRSA";

    //前置系统公钥
    private static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9vGvYjivDF5uPBNDXMtoAtjYQ2YPSsfareduDG6kHL/N3A05rFHA11Dbr+UON82Y4V0RFKAQeZFPWcTLjcy6ntZVI8XoYLpuVQBPsb0Ya+PwbzR8/TmUdUf91ru8APtJgqkULgPVrO1hhzZ1tQMznosNLTOqbknMnnMcwzB5yYwIDAQAB";

    //测试环境商户私钥
    private static String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJFNKoOV2cJKFLkkTqVEqWX55CxSEiE4816Nc9y12vv387kKEPpyP81vISF9eoolQAu3v3V019Krx+83tmeb86oWAf3C0eEdLhl2RUOYGrwBDdNKkr+BCnbd6P6vpdfluah+t3g/EirBAzpf8qMkzY3pnx7UrX98fdD/Abl9+fEHAgMBAAECgYANvLHsRtqTl9Vlu50D2v34+issVYYJRg0cP1tY3oiZkdOlBuKcCvklPwBu3iIbtXHcqb6cKDPPYxY/85B3MzNSGMPWn7xA0JtMcDOF7sHMxSxg2Jy3Kh2f+kt3Pvcnv/cfmL+mV1xl6918qaaNpyBka+xvmWkp/g+2Nn/5xVtpwQJBAMwK5dnGIUPmccEOutNVrm5V8fNv+Li+tp7ft0hFNX8b7yG6P/OsMduWaZPElExDJ/auk7b50zv/LjEtodIvWS8CQQC2TQ7WlRB2xommVytMTOw7Pn16RfzfkOlmuTnAW5BsSCIl/G5gxR0UOGdkbI7b7T9DY8E/Yo0MXWfglB9iMr+pAkEAk5y+tFG19x1b5kL1vbYavw/GPksfMOgnzcAjJFGNZiubUFchtPM6DpY+QvzQHGvpGXkqvBD4VEtD66gLjbdbWQJADP7xT9rQkacVqQYN0CKrtI1/5HeYz1dFTE1oEI52fUGnLY4RUFS8/fQHauFSTdtb5zH1VM9xvq/p99iXZCi6AQJAHtpfzcsdAIjxPoIyYIRpPy/pd5j8cegReRrmA3eg8K0ivR0zDRfwZ6WGJVIh1K8QLgov8yVLUI9jUk1HvzPbaQ==";

    private XSpayService() {
    }

    public void init(String pbk, String pvk) {
        publicKey = pbk;
        privateKey = pvk;
    }

    public static XSpayService getInstance() {
        if (instance == null) {
            synchronized (XSpayService.class) {
                if (instance == null) {
                    instance = new XSpayService();
                }
            }
        }
        return instance;
    }

    public Map<String, Object> post(BaseTransForm base, String[] verifyFields) throws Exception {
        PrivateKey privateKey = KeyUtils.loadPrivateKey(XSpayService.privateKey, ALGORITHM);

        //4，获取加密字段的json串（明文）
        String encryptStr = base.getEncryptJsonStr();
        logger.debug("待加密字符串为：" + encryptStr);

        //5，使用平台公钥进行rsa加密
        String msgCipherText = Base64Util.encode(HnapaySign.encryptByPublicKey(encryptStr.getBytes(), publicKey, ALGORITHM)).replace("\n", "").replace("\r", "");
        logger.debug("加密后字符串为：" + msgCipherText);

        base.setMsgCiphertext(msgCipherText);

        //6，使用商户私钥进行签名
        logger.debug("待签名字符串：" + base.getCommonSignStr());
        String signValue = Base64Util.encode(HnapaySign.sign(privateKey, base.getCommonSignStr(), SIGN_ALGORITHM)).replace("\n", "").replace("\r", "");
        logger.debug("签名后字符串为：" + signValue);

        base.setSignValue(signValue);

        //7，构建提交至平台的请求参数
        Map<String, Object> reqMap = base.getCommonReqSignParams();
        reqMap.put("signValue", base.getSignValue());
        reqMap.put("charset", "1");
        logger.debug("提交字符串为：" + JSONObject.toJSONString(reqMap));

        String response;
        if (base.getSubmitUrl().startsWith("https://")) {
            HttpsTransport httpsTransport = new HttpsTransport();
            httpsTransport.setSendEncoding("UTF-8");
            httpsTransport.setUrl(base.getSubmitUrl());
            response = (String) httpsTransport.submit(reqMap);
        } else {
            HttpClientUtils httpClientUtils = new HttpClientUtils();
            response = httpClientUtils.submit(reqMap, base.getSubmitUrl());
        }

        logger.debug("响应字符串为：" + JSONObject.toJSONString(response));

        //8，返回参数转map
        Map<String, Object> responseMap = JSONObject.parseObject(response);
        boolean verifyResult = isVerifyResult(verifyFields, responseMap);

        if (verifyResult) {
            return responseMap;
        } else {
            return null;
        }
    }

    public static boolean isVerifyResult(String[] verifyFields, Map<String, Object> responseMap) throws XSpayException {
        //9，根据交易码构建不同接口验签明文串
        String verifyFieldStr = getVerifyData(verifyFields, responseMap);
        logger.debug("验签明文字符串为：" + verifyFieldStr);

        //10，使用平台公钥进行验签
        boolean verifyResult = HnapaySign.verify(verifyFieldStr, responseMap.get("signValue").toString(), publicKey, SIGN_ALGORITHM, ALGORITHM);
        logger.debug("验签结果为：" + verifyResult);
        return verifyResult;
    }


    private static String getVerifyData(String[] verifyFields, Map<String, Object> responseMap) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < verifyFields.length; i++) {
            sb.append(verifyFields[i]);
            sb.append("=[");
            sb.append(responseMap.get(verifyFields[i]) == null ? "" : responseMap.get(verifyFields[i]));
            sb.append("]");
        }

        return sb.toString();

    }
}
